﻿using Lanting.Utilities;
using Lanting.Utilities.NetConn;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace Lanting.Utilities.NetConn
{
    public class NetUtils
    {
        #region 方法-创建Post方式的Http请求
        /// <summary>  
        /// 创建POST方式的HTTP请求  
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static Result HttpPost<O, L>(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
        {
            Result result = new Result();
            try
            {
                #region 网络通信-获取服务器响应结果
                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("url");
                }
                if (requestEncoding == null)
                {
                    throw new ArgumentNullException("requestEncoding");
                }
                HttpWebRequest request = null;
                //如果是发送HTTPS请求  
                //if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                //{
                //    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                //    request = WebRequest.Create(url) as HttpWebRequest;
                //    request.ProtocolVersion = HttpVersion.Version10;
                //}
                //else
                //{
                //    request = WebRequest.Create(url) as HttpWebRequest;
                //}
                request = WebRequest.Create(url) as HttpWebRequest;

                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";

                if (!string.IsNullOrEmpty(userAgent))
                {
                    request.UserAgent = userAgent;
                }
                else
                {
                    //request.UserAgent = DefaultUserAgent;
                }

                if (timeout.HasValue)
                {
                    request.Timeout = timeout.Value;
                }
                if (cookies != null)
                {
                    request.CookieContainer = new CookieContainer();
                    request.CookieContainer.Add(cookies);
                }
                //如果需要POST数据  
                if (!(parameters == null || parameters.Count == 0))
                {
                    StringBuilder buffer = new StringBuilder();
                    int i = 0;
                    foreach (string key in parameters.Keys)
                    {
                        if (i > 0)
                        {
                            buffer.AppendFormat("&{0}={1}", key, System.Web.HttpUtility.UrlEncode(parameters[key], Encoding.UTF8));
                        }
                        else
                        {
                            buffer.AppendFormat("{0}={1}", key, System.Web.HttpUtility.UrlEncode(parameters[key], Encoding.UTF8));
                        }

                        //if (i > 0)
                        //{
                        //    buffer.AppendFormat("&{0}={1}", key, UtilMethods.Function_UrlEncode(parameters[key]));
                        //}
                        //else
                        //{
                        //    buffer.AppendFormat("{0}={1}", key, UtilMethods.Function_UrlEncode(parameters[key]));
                        //}

                        i++;
                    }
                    byte[] data = requestEncoding.GetBytes(buffer.ToString());
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                }

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream instream = response.GetResponseStream();
                StreamReader sr = new StreamReader(instream, Encoding.UTF8);
                //返回结果网页（html）代码
                string str_content = sr.ReadToEnd();
                #endregion

                #region 反序列化 string->对象 string->list   
                if (!string.IsNullOrEmpty(str_content))
                {
                    result = JsonConvert.DeserializeObject<Result>(str_content);
                    JObject jsonObj = JObject.Parse(str_content);
                    if (jsonObj.GetValue("obj") != null)
                    {
                        try
                        {
                            string str_obj = JsonConvert.SerializeObject(jsonObj.GetValue("obj"));
                            result.obj = JsonConvert.DeserializeObject<O>(str_obj);
                        }
                        catch (Exception ex)
                        {
                            
                        }           
                    }
                    if (jsonObj.GetValue("list") != null)
                    {
                        try
                        {
                            string str_obj = JsonConvert.SerializeObject(jsonObj.GetValue("list"));
                            JsonSerializer serializer = new JsonSerializer();
                            StringReader strReader = new StringReader(str_obj);
                            object o = serializer.Deserialize(new JsonTextReader(strReader), typeof(List<L>));
                            result.list = o as List<L>;
                        }
                        catch (Exception ex)
                        {
                            
                        }
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                result.status = Params.status_fail;
                result.info = ex.Message;
            }
            return result;
        }
        #endregion

        #region 将本地文件上传到指定的服务器(HttpWebRequest方法)  
        /// <summary>
        /// 将本地文件上传到指定的服务器(HttpWebRequest方法)  
        /// </summary>
        /// <param name="strAddress">服务器IP地址全路径</param>
        /// <param name="fileNamePath">本地文件全路径</param>
        /// <param name="saveName">在服务器上的另存名</param>
        /// <returns></returns>
        public static Result Upload_Request<O, L>(string strAddress, string fileNamePath, string saveName, Dictionary<string, string> mParams)
        {
            Result result = new Result();

            try
            {
                #region 传参数部分-url拼装
                strAddress += "?";
                foreach (string key in mParams.Keys)
                {
                    strAddress = strAddress + key + "=" + mParams[key] + "&";
                }
                if (strAddress.Length - 1 == strAddress.LastIndexOf('&'))
                {
                    strAddress = strAddress.Substring(0, strAddress.Length - 1);
                }
                #endregion

                HttpWebRequest request = WebRequest.Create(strAddress) as HttpWebRequest;
                CookieContainer cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
                request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;

                if (!String.IsNullOrEmpty(fileNamePath))
                {
                    #region 文件参数组装
                    byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
                    byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
                    StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", saveName));
                    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
                    FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
                    byte[] bArr = new byte[fs.Length];
                    fs.Read(bArr, 0, bArr.Length);
                    fs.Close();
                    #endregion

                    Stream postStream = request.GetRequestStream();

                    #region 传参数部分-取消post
                    //string PREFIX = "--", LINE_END = "\r\n";
                    //foreach (string key in mParams.Keys)
                    //{
                    //    string value = mParams[key];
                    //    StringBuilder sb = new StringBuilder();
                    //    sb.Append(PREFIX).Append(boundary).Append(LINE_END);
                    //    sb.Append("Content-Disposition: form-data; name=\"").Append(key).Append("\"").Append(LINE_END).Append(LINE_END);
                    //    sb.Append(value).Append(LINE_END);
                    //    String str_params = sb.ToString();
                    //    byte[] data = Encoding.Default.GetBytes(str_params);
                    //    postStream.Write(data, 0, data.Length);
                    //}
                    #endregion

                    #region 传文件部分
                    postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
                    postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                    postStream.Write(bArr, 0, bArr.Length);
                    postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                    postStream.Close();
                    #endregion
                }


                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream instream = response.GetResponseStream();
                StreamReader sr = new StreamReader(instream, Encoding.UTF8);
                //返回结果网页（html）代码
                //string line = sr.ReadLine();
                string str_content = sr.ReadToEnd();

                #region 反序列化 string->对象 string->list   
                if (!string.IsNullOrEmpty(str_content))
                {
                    result = JsonConvert.DeserializeObject<Result>(str_content);
                    JObject jsonObj = JObject.Parse(str_content);
                    if (jsonObj.GetValue("obj") != null)
                    {
                        string str_obj = JsonConvert.SerializeObject(jsonObj.GetValue("obj"));
                        result.obj = JsonConvert.DeserializeObject<O>(str_obj);
                    }
                    if (jsonObj.GetValue("list") != null)
                    {
                        string str_obj = JsonConvert.SerializeObject(jsonObj.GetValue("list"));
                        JsonSerializer serializer = new JsonSerializer();
                        StringReader strReader = new StringReader(str_obj);
                        object o = serializer.Deserialize(new JsonTextReader(strReader), typeof(List<L>));
                        result.list = o as List<L>;
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                result.status = Params.status_fail;
                result.info = ex.Message;
            }
            return result;
        }
        #endregion      
    }
}
